package kotan.view.table.editor;

import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;

import javax.swing.BorderFactory;
import javax.swing.ButtonGroup;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JTextField;

import kotan.Kotan;
import kotan.datastore.api.Entity;
import kotan.datastore.api.Key;
import kotan.model.EntityModel;
import kotan.model.KindModel;
import kotan.util.KeyFactory;

public class KeyEditorPanel extends JPanel {

    private static final long serialVersionUID = 1L;
    KindModel model;
    Key key;
    JTextField kindField;
    JTextField idField;
    JButton applyButton;
    private JRadioButton longTypeButton;
    private JRadioButton stringTypeButton;

    public KeyEditorPanel() {
        initComponents();
        this.setBorder(BorderFactory.createEmptyBorder(2, 5, 3, 5));
        this.setPreferredSize(new Dimension(500, 250));
    }

    private void initComponents() {
        // Kind
        JLabel kindLabel = new JLabel();
        kindLabel.setText("Kind: ");
        kindField = new JTextField();
        kindField.setEditable(false);
        kindField.setFocusable(false);
        // Id
        JLabel idLabel = new JLabel();
        idLabel.setText("Id: ");
        idField = new JTextField();
        // Id type
        JLabel idTypeLabel = new JLabel();
        idTypeLabel.setText("Id Type: ");
        longTypeButton = new JRadioButton();
        longTypeButton.setText("Long");
        longTypeButton.setSelected(true);
        stringTypeButton = new JRadioButton();
        stringTypeButton.setText("String");
        ButtonGroup idTypeGroup = new ButtonGroup();
        idTypeGroup.add(longTypeButton);
        idTypeGroup.add(stringTypeButton);
        // parent key
        JLabel parentKeyLabel = new JLabel();
        parentKeyLabel.setText("Parent Key: ");
        List<String> kinds = Kotan.get().getDatastore().getKindList();
        kinds.add(0, "");
        final JComboBox kindComboBox = new JComboBox(kinds.toArray());
        final JComboBox keyComboBox = new JComboBox();
        keyComboBox.setEnabled(false);
        kindComboBox.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent evt) {
                String kind = (String) kindComboBox.getSelectedItem();
                if (kind.length() == 0) {
                    keyComboBox.setEnabled(false);
                } else {
                    keyComboBox.setEnabled(true);
                    keyComboBox
                        .setModel(new DefaultComboBoxModel(Kotan.get().getDatastore().getKeyList(kind).toArray()));
                }
            }
        });
        // Apply / Cancel
        applyButton = new JButton();
        applyButton.setText("Apply");
        applyButton.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                onApply();
            }
        });
        JButton cancelButton = new JButton();
        cancelButton.setText("Cancel");
        cancelButton.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                onCancel();
            }
        });
        // Layout
        this.setLayout(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.gridwidth = 1;
        gbc.weightx = 0.0;
        gbc.weighty = 0.0;
        gbc.anchor = GridBagConstraints.EAST;
        gbc.fill = GridBagConstraints.NONE;
        gbc.insets = new Insets(3, 5, 2, 5);
        add(kindLabel, gbc);
        gbc.gridx = 1;
        gbc.gridy = 0;
        gbc.gridwidth = 2;
        gbc.weightx = 1.0;
        gbc.weighty = 0.0;
        gbc.anchor = GridBagConstraints.WEST;
        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.insets = new Insets(3, 5, 2, 5);
        add(kindField, gbc);
        //
        gbc.gridx = 0;
        gbc.gridy = 1;
        gbc.gridwidth = 1;
        gbc.weightx = 0.0;
        gbc.weighty = 0.0;
        gbc.anchor = GridBagConstraints.EAST;
        gbc.fill = GridBagConstraints.NONE;
        gbc.insets = new Insets(3, 5, 2, 5);
        add(idLabel, gbc);
        gbc.gridx = 1;
        gbc.gridy = 1;
        gbc.gridwidth = 2;
        gbc.weightx = 1.0;
        gbc.weighty = 0.0;
        gbc.anchor = GridBagConstraints.WEST;
        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.insets = new Insets(3, 5, 2, 5);
        add(idField, gbc);
        //
        gbc.gridx = 0;
        gbc.gridy = 2;
        gbc.gridwidth = 1;
        gbc.weightx = 0.0;
        gbc.weighty = 0.0;
        gbc.anchor = GridBagConstraints.EAST;
        gbc.fill = GridBagConstraints.NONE;
        gbc.insets = new Insets(3, 5, 2, 5);
        add(idTypeLabel, gbc);
        gbc.gridx = 1;
        gbc.gridy = 2;
        gbc.gridwidth = 1;
        gbc.weightx = 0.0;
        gbc.weighty = 0.0;
        gbc.anchor = GridBagConstraints.WEST;
        gbc.fill = GridBagConstraints.NONE;
        gbc.insets = new Insets(3, 5, 2, 5);
        add(longTypeButton, gbc);
        gbc.gridx = 2;
        gbc.gridy = 2;
        gbc.gridwidth = 1;
        gbc.weightx = 1.0;
        gbc.weighty = 0.0;
        gbc.anchor = GridBagConstraints.WEST;
        gbc.fill = GridBagConstraints.NONE;
        gbc.insets = new Insets(3, 5, 2, 5);
        add(stringTypeButton, gbc);
        //
        gbc.gridx = 0;
        gbc.gridy = 3;
        gbc.gridwidth = 1;
        gbc.weightx = 0.0;
        gbc.weighty = 0.0;
        gbc.anchor = GridBagConstraints.EAST;
        gbc.fill = GridBagConstraints.NONE;
        gbc.insets = new Insets(3, 5, 2, 5);
        add(parentKeyLabel, gbc);
        gbc.gridx = 1;
        gbc.gridy = 3;
        gbc.gridwidth = 2;
        gbc.weightx = 1.0;
        gbc.weighty = 0.0;
        gbc.anchor = GridBagConstraints.WEST;
        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.insets = new Insets(3, 5, 2, 5);
        {
            JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEFT));
            panel.add(kindComboBox);
            panel.add(keyComboBox);
            add(panel, gbc);
        }
        // 
        gbc.gridx = 0;
        gbc.gridy = 10;
        gbc.gridwidth = 3;
        gbc.weightx = 1.0;
        gbc.weighty = 1.0;
        gbc.anchor = GridBagConstraints.NORTHEAST;
        gbc.fill = GridBagConstraints.NONE;
        gbc.insets = new Insets(3, 5, 2, 5);
        {
            JPanel panel = new JPanel(new FlowLayout());
            panel.add(cancelButton);
            panel.add(applyButton);
            add(panel, gbc);
        }
    }

    protected void onApply() {
        String kind = kindField.getText();
        Key newKey;
        if (longTypeButton.isSelected()) {
            newKey = KeyFactory.createKey(kind, Long.parseLong(idField.getText()));
        } else {
            newKey = KeyFactory.createKey(kind, idField.getText());
        }
        if (key.equals(newKey) && model.contains(newKey)) return;
        EntityModel entityModel = model.get(key);
        Entity newEntity = new Entity(newKey);
        if (entityModel != null) {
            newEntity.setPropertiesFrom(entityModel.getEntity());
        }
        EntityModel newModel = new EntityModel(newEntity);
        Kotan.get().getDatastore().add(newModel);
        if (!key.equals(newKey)) Kotan.get().getDatastore().delete(key);
    }

    protected void onCancel() {
    }

    void init(KindModel model, Key key) {
        this.model = model;
        this.kindField.setText(model.getName());
        this.key = key;
        if (key.getName() != null) {
            this.idField.setText(key.getName());
            this.stringTypeButton.setSelected(true);
        } else {
            this.idField.setText(Long.toString(key.getId()));
            this.longTypeButton.setSelected(true);
        }
    }
}
